// Koswin.cpp : Defines the entry point for the application.
//
#include "Koswin.h"
#include "mmsystem.h"
#include <share.h>
#include <sys/stat.h>

#ifdef _DEBUG
//#include <dxerr8.h>
#endif

//agmmodel mod_echo;
//GLuint tex_echo;
//float ry;
DWORD KoswinNewTime,KoswinOldTime;
WinInput JoyInput;


void glKosShutdown() {};
void glKosInit(){};
void pvr_init(){};
void KOS_INIT_ROMDISK(){};

int fs_open(const char* filename, int openflag)
{
	int fileHandle = 0;
	
	if (openflag & _O_RDONLY)
	{
		if (_sopen_s(&fileHandle, filename, openflag, _SH_DENYRW, _S_IREAD) != 0)
			return 0;
	}
	else
	{
		if (_sopen_s(&fileHandle, filename, openflag, _SH_DENYRW, _S_IWRITE) != 0)
			return 0;
	}

	return fileHandle;
}

int cont_get_cond(uint8 c,cont_cond_t* cond)
{
	HRESULT hr;
	unsigned short btn;
	
	if ((hr=JoyInput.Update()) == S_OK) {
		cond->buttons=(uint16)0xFFFF;
		cond->joyx=(uint8)0x80;//(uint8)(JoyInput.JoyState.lX>>24);
		cond->joyy=(uint8)0x80;//(uint8)(JoyInput.JoyState.lY>>24);
		cond->rtrig=(uint8)0x00;
		cond->ltrig=(uint8)0x00;

		//joystick
		btn=CONT_A;
		if (JoyInput.JoyState.rgbButtons[0]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_B;
		if (JoyInput.JoyState.rgbButtons[1]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_X;
		if (JoyInput.JoyState.rgbButtons[2]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_Y;
		if (JoyInput.JoyState.rgbButtons[3]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_START;
		if (JoyInput.JoyState.rgbButtons[4]&0x80) cond->buttons=cond->buttons&(~btn);

		if (JoyInput.JoyState.rgbButtons[5]&0x80) cond->rtrig=(uint8)0xFF;


#ifdef ANALOGMAIN

		 //JS reports in range 0x0 to 0xFFFF, joyx needs 0x0 to 0xFF 
		float joyX = ((float)JoyInput.JoyState.lX/(2000.0f/256.0f)) + 128;
		float joyY = ((float)JoyInput.JoyState.lY/(2000.0f/256.0f)) + 128;
		cond->joyx=(uint8)(min(255,max(0, joyX)));
		cond->joyy=(uint8)(min(255,max(0, joyY)));

		if (LOWORD(JoyInput.JoyState.rgdwPOV[0]) != 0xFFFF)
		{
			btn=CONT_DPAD_LEFT;
			if (JoyInput.JoyState.rgdwPOV[0] > 18000 && JoyInput.JoyState.rgdwPOV[0] < 36000) cond->buttons=cond->buttons&(~btn);
			btn=CONT_DPAD_RIGHT;
			if (JoyInput.JoyState.rgdwPOV[0] > 0000 && JoyInput.JoyState.rgdwPOV[0] < 18000) cond->buttons=cond->buttons&(~btn);
			btn=CONT_DPAD_UP;
			if (JoyInput.JoyState.rgdwPOV[0] > 27000 || JoyInput.JoyState.rgdwPOV[0] < 9000) cond->buttons=cond->buttons&(~btn);
			btn=CONT_DPAD_DOWN;
			if (JoyInput.JoyState.rgdwPOV[0] < 27000 && JoyInput.JoyState.rgdwPOV[0] > 9000) cond->buttons=cond->buttons&(~btn);
		}
#else
		btn=CONT_DPAD_LEFT;
		if ((JoyInput.JoyState.lX)<-250) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_RIGHT;
		if ((JoyInput.JoyState.lX)>250) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_UP;
		if ((JoyInput.JoyState.lY)<-250) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_DOWN;
		if ((JoyInput.JoyState.lY)>250) cond->buttons=cond->buttons&(~btn);

		if (LOWORD(JoyInput.JoyState.rgdwPOV[0]) != 0xFFFF)
		{
			if (JoyInput.JoyState.rgdwPOV[0] > 18000 && JoyInput.JoyState.rgdwPOV[0] < 36000) cond->joyx = 0;
			if (JoyInput.JoyState.rgdwPOV[0] > 0000 && JoyInput.JoyState.rgdwPOV[0] < 18000) cond->joyx = 255;
			if (JoyInput.JoyState.rgdwPOV[0] > 27000 || JoyInput.JoyState.rgdwPOV[0] < 9000) cond->joyy = 0;
			if (JoyInput.JoyState.rgdwPOV[0] < 27000 && JoyInput.JoyState.rgdwPOV[0] > 9000) cond->joyy = 255;
		}
#endif

		//keyboard
		btn=CONT_A;
		if (JoyInput.KeyState[DIK_Z]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_B;
		if (JoyInput.KeyState[DIK_X]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_X;
		if (JoyInput.KeyState[DIK_A]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_Y;
		if (JoyInput.KeyState[DIK_S]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_START;
		if (JoyInput.KeyState[DIK_RETURN]&0x80) cond->buttons=cond->buttons&(~btn);

		if (JoyInput.KeyState[DIK_W]&0x80) cond->rtrig=(uint8)0xFF;
		if (JoyInput.KeyState[DIK_Q]&0x80) cond->ltrig=(uint8)0xFF;
	


#ifdef ANALOGMAIN
		btn=CONT_DPAD_UP;
		if (JoyInput.KeyState[DIK_NUMPAD8]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_DOWN;
		if (JoyInput.KeyState[DIK_NUMPAD5]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_LEFT;
		if (JoyInput.KeyState[DIK_NUMPAD4]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_RIGHT;
		if (JoyInput.KeyState[DIK_NUMPAD6]&0x80) cond->buttons=cond->buttons&(~btn);
		
		if (JoyInput.KeyState[DIK_UP]&0x80) cond->joyy=(uint8)0x00;
		if (JoyInput.KeyState[DIK_DOWN]&0x80) cond->joyy=(uint8)0xFF;
		if (JoyInput.KeyState[DIK_LEFT]&0x80) cond->joyx=(uint8)0x00;
		if (JoyInput.KeyState[DIK_RIGHT]&0x80) cond->joyx=(uint8)0xFF;

#else
		btn=CONT_DPAD_UP;
		if (JoyInput.KeyState[DIK_UP]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_DOWN;
		if (JoyInput.KeyState[DIK_DOWN]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_LEFT;
		if (JoyInput.KeyState[DIK_LEFT]&0x80) cond->buttons=cond->buttons&(~btn);
		btn=CONT_DPAD_RIGHT;
		if (JoyInput.KeyState[DIK_RIGHT]&0x80) cond->buttons=cond->buttons&(~btn);
		
		if (JoyInput.KeyState[DIK_NUMPAD8]&0x80) cond->joyy=(uint8)0x00;
		if (JoyInput.KeyState[DIK_NUMPAD5]&0x80) cond->joyy=(uint8)0xFF;
		if (JoyInput.KeyState[DIK_NUMPAD4]&0x80) cond->joyx=(uint8)0x00;
		if (JoyInput.KeyState[DIK_NUMPAD6]&0x80) cond->joyx=(uint8)0xFF;
#endif

	}else{
#ifdef _DEBUG
		//MessageBox(NULL,DXGetErrorString8(hr),"error",MB_OK);	
		MessageBox(NULL,L"Error",L"error",MB_OK);	
#endif
	}
	return 1;
}


maple_device_t dummydevice;
maple_device_t* maple_enum_type(int n, uint32 func)
{
	return &dummydevice;
}



int testButton(bool on, int button)
{
	if (on)
		return button;

	return 0;
}

cont_state_t controller;
void* maple_dev_status(maple_device_t *dev) 
{
	HRESULT hr;
	
	controller.buttons=0;
	controller.joyx=0;
	controller.joyy=0;
	controller.joy2x=0;
	controller.joy2y=0;
	controller.rtrig=0x00;
	controller.ltrig=0x00;

	if ((hr=JoyInput.Update()) == S_OK) 
	{
		//joystick
		controller.buttons |= (JoyInput.JoyState.rgbButtons[0]&0x80)?CONT_A:0;
		controller.buttons |= (JoyInput.JoyState.rgbButtons[1]&0x80)?CONT_B:0;
		controller.buttons |= (JoyInput.JoyState.rgbButtons[2]&0x80)?CONT_X:0;
		controller.buttons |= (JoyInput.JoyState.rgbButtons[3]&0x80)?CONT_Y:0;
		controller.buttons |= (JoyInput.JoyState.rgbButtons[4]&0x80)?CONT_START:0;
		controller.rtrig = (JoyInput.JoyState.rgbButtons[5]&0x80)?0xFF:0;

		//keyboard
		controller.buttons |= (JoyInput.KeyState[DIK_Z]&0x80)?CONT_A:0;
		controller.buttons |= (JoyInput.KeyState[DIK_X]&0x80)?CONT_B:0;
		controller.buttons |= (JoyInput.KeyState[DIK_A]&0x80)?CONT_X:0;
		controller.buttons |= (JoyInput.KeyState[DIK_S]&0x80)?CONT_Y:0;
		controller.buttons |= (JoyInput.KeyState[DIK_RETURN]&0x80)?CONT_START:0;

		controller.rtrig = (JoyInput.KeyState[DIK_W]&0x80)?0xFF:0;
		controller.rtrig = (JoyInput.KeyState[DIK_Q]&0x80)?0xFF:0;

#ifdef ANALOGMAIN
		//joystick
		//report in range -1000 to 1000?
		controller.joyx=(int)(JoyInput.JoyState.lX/2.0f);
		controller.joyy=(int)(JoyInput.JoyState.lY/2.0f);
		
		//keyboard
		controller.buttons |= (JoyInput.KeyState[DIK_NUMPAD8]&0x80)?CONT_DPAD_UP:0;
		controller.buttons |= (JoyInput.KeyState[DIK_NUMPAD5]&0x80)?CONT_DPAD_DOWN:0;
		controller.buttons |= (JoyInput.KeyState[DIK_NUMPAD4]&0x80)?CONT_DPAD_LEFT:0;
		controller.buttons |= (JoyInput.KeyState[DIK_NUMPAD6]&0x80)?CONT_DPAD_RIGHT:0;
		
		//report in range -1000 to 1000?
		if (JoyInput.KeyState[DIK_UP]&0x80) controller.joyy=-1000;
		if (JoyInput.KeyState[DIK_DOWN]&0x80) controller.joyy=1000;
		if (JoyInput.KeyState[DIK_LEFT]&0x80) controller.joyx=-1000;
		if (JoyInput.KeyState[DIK_RIGHT]&0x80) controller.joyx=1000;
#else
		//joystick
		controller.buttons |= ((JoyInput.JoyState.lX)<-250)?CONT_DPAD_LEFT:0;
		controller.buttons |= ((JoyInput.JoyState.lX)>250)?CONT_DPAD_RIGHT:0;
		controller.buttons |= ((JoyInput.JoyState.lY)<-250)?CONT_DPAD_UP:0;
		controller.buttons |= ((JoyInput.JoyState.lY)>250)?CONT_DPAD_DOWN:0;

		//keyboard
		controller.buttons |= (JoyInput.KeyState[DIK_UP]&0x80)?CONT_DPAD_UP:0;
		controller.buttons |= (JoyInput.KeyState[DIK_DOWN]&0x80)?CONT_DPAD_DOWN:0;
		controller.buttons |= (JoyInput.KeyState[DIK_LEFT]&0x80)?CONT_DPAD_LEFT:0;
		controller.buttons |= (JoyInput.KeyState[DIK_RIGHT]&0x80)?CONT_DPAD_RIGHT:0;
		
		//report in range -1000 to 1000?
		if (JoyInput.KeyState[DIK_NUMPAD8]&0x80) controller.joyy=-1000;
		if (JoyInput.KeyState[DIK_NUMPAD5]&0x80) controller.joyy=1000;
		if (JoyInput.KeyState[DIK_NUMPAD4]&0x80) controller.joyx=-1000;
		if (JoyInput.KeyState[DIK_NUMPAD6]&0x80) controller.joyx=1000;
#endif

	}else{
#ifdef _DEBUG
		//MessageBox(NULL,DXGetErrorString8(hr),"error",MB_OK);	
		MessageBox(NULL,L"Error",L"error",MB_OK);	
#endif
	}

	return (void *)(&controller);
}



void gettimeofday(timeval* time, timezone* tz) {
	uint32 tgt=timeGetTime();
	time->tv_sec=tgt/1000;
	time->tv_usec=(tgt-(time->tv_sec*1000))*1000;
};

void vid_screen_shot(char* fn) {};

int snd_stream_init(char* unkn) {return 1;};
int snd_sfx_load(char* sound){return 1;}
int	snd_sfx_unload_all() {return 1;};
int	snd_stream_shutdown() {return 1;};
void snd_sfx_play(int idx, int vol, int pan) {};
int maple_first_controller(){return 1;};


void loadpng(const char *fn, uint32 alpha, GLuint *txr) {
	uint32 w, h;

	void   (__cdecl* PNGFunc)(const char *, char*, uint32,uint32*, uint32*);

	HINSTANCE PNGlibhandle=LoadLibrary(L"txalib.dll");

	if (PNGlibhandle==NULL) {
		MessageBox(NULL,L"failed to load txa library",L"error",MB_OK);
		return;
	}
	PNGFunc=(void (__cdecl *)(const char *, char*, uint32,uint32*, uint32*))GetProcAddress(PNGlibhandle,"PngLoadTex");
	if (PNGFunc==NULL) {
		MessageBox(NULL,L"failed to load txa function",L"error",MB_OK);
		return;
	}


//	txaddr = ta_txr_allocate(w * h *2);
//	png_to_texture(*fn, txaddr, PNG_NO_ALPHA);

	char* txaddr = new char[512 * 512 * 4];

	PNGFunc(fn, txaddr, alpha, &w, &h);
	glGenTextures(1, txr);
	glBindTexture(GL_TEXTURE_2D, *txr);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	gluBuild2DMipmaps( GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, txaddr);

	delete txaddr;
	FreeLibrary(PNGlibhandle);
}

void loadjpg(const char *fn, uint32 width, GLuint *txr) {

	void   (__cdecl* JpegFunc)(const char *, char*, int, int);

	HINSTANCE Jpglibhandle=LoadLibrary(L"txrlib.dll");

	if (Jpglibhandle==NULL) {
		MessageBox(NULL,L"failed to load txr library",L"error",MB_OK);
		return;
	}
	JpegFunc=(void (__cdecl * )(const char *, char*, int, int))GetProcAddress(Jpglibhandle,"JpegToTex");
	if (JpegFunc==NULL) {
		MessageBox(NULL,L"failed to load txr function",L"error",MB_OK);
		return;
	}

	char* txaddr = new char[width * width * 3];

	JpegFunc(fn, txaddr, width, 1);
	glGenTextures(1, txr);
	glBindTexture(GL_TEXTURE_2D, *txr);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//	glTexImage2D(GL_TEXTURE_2D, 0, 3, width, width, 0,GL_RGB, GL_UNSIGNED_BYTE, txaddr);
	gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, width, GL_RGB, GL_UNSIGNED_BYTE, txaddr);

	delete txaddr;
	FreeLibrary(Jpglibhandle);
}

void glKosBeginFrame() {
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}

void glKosFinishList() {
	
};

void glKosFinishFrame() {
	glFlush();
	SwapBuffers(hDC);
};

